
import SQLite

class DbGroup : DbBase {
    var group: Table = Table("group")
    let _id = Expression<Int64>("id")
    let _isNull = Expression<Bool>("isNull")
    let _groupId = Expression<String>("groupId")
    let _owner = Expression<String>("owner")
    let _name = Expression<String>("name")
    let _alias = Expression<String>("alias")
    let _portrait = Expression<String>("portrait")
    let _extra = Expression<String>("extra")
    let _attribute = Expression<String>("attribute")
    let _billboard = Expression<String>("billboard")
    let _isMember = Expression<String>("isMember")
    let _type = Expression<Int>("type")
    let _passType = Expression<Int>("passType")
    let _joinType = Expression<String>("joinType")
    let _joinPwd = Expression<String>("joinPwd")
    let _mute = Expression<Int>("mute")
    let _singleMute = Expression<Int>("singleMute")
    let _muteRange = Expression<Int>("muteRange")
    let _memberCount = Expression<Int>("memberCount")
    let _maxMember = Expression<Int>("maxMember")
    let _isAdmin = Expression<Bool>("isAdmin")
    let _fav = Expression<Bool>("fav")
    let _showAlias = Expression<Bool>("showAlias")
    let _timestamp = Expression<Int64>("timestamp")
    
    func open(){
        do{
            try getDb()!.run(group.create(ifNotExists: true) { t in
                t.column(_id, primaryKey: .autoincrement)
                t.column(_groupId, unique: true)
                t.column(_isNull)
                t.column(_owner)
                t.column(_name)
                t.column(_alias)
                t.column(_portrait)
                t.column(_extra)
                t.column(_attribute)
                t.column(_billboard)
                t.column(_isMember)
                t.column(_type)
                t.column(_passType)
                t.column(_joinType)
                t.column(_joinPwd)
                t.column(_mute)
                t.column(_singleMute)
                t.column(_muteRange)
                t.column(_memberCount)
                t.column(_maxMember)
                t.column(_isAdmin)
                t.column(_fav)
                t.column(_showAlias)
                t.column(_timestamp)
            })
            try getDb()!.run(group.createIndex(_groupId, ifNotExists: true))

        }catch{
            print("\(error)")
        }
    }
    private func toInfo(_ row:Row) -> DMCCGroup{
        let g = DMCCGroup()
        g.id = row[_id]
        g.isNull = row[_isNull]
        g.groupId = row[_groupId]
        g.owner = row[_owner]
        g.name = row[_name]
        g.alias = row[_alias]
        g.portrait = row[_portrait]
        g.isMember = row[_isMember]
        g.type = row[_type]
        g.passType = row[_passType]
        g.singleMute = row[_singleMute]
        g.showAlias = row[_showAlias]
        g.isAdmin = row[_isAdmin]
        g.fav = row[_fav]
        g.extra = row[_extra]
        g.attribute = row[_attribute]
        g.billboard = row[_billboard]
        g.timestamp = row[_timestamp]
        g.joinPwd = row[_joinPwd]
        g.memberCount = row[_memberCount]
        g.maxMemberCount = row[_maxMember]
        g.mute = row[_mute]
        g.muteRange = OsnMuteRange(rawValue: row[_muteRange])
        g.joinType = OsnJoinType(rawValue: row[_joinType])
        return g
    }
    func getGroupInfo(_ osnId:String) -> DMCCGroup? {
        do{
            for groups in try getDb()!.prepare(group.filter(osnId == _groupId)) {
                return toInfo(groups)
            }
        }catch{
            print("\(error)")
        }
        return nil
    }
    func addGroupInfo(_ info:DMCCGroup) -> Bool {
        do{
            return try getDb()!.run(group.upsert(
                _isNull <- info.isNull,
                _groupId <- info.groupId,
                _owner <- info.owner,
                _name <- info.name,
                _alias <- info.alias,
                _portrait <- info.portrait,
                _extra <- info.extra,
                _attribute <- info.attribute,
                _billboard <- info.billboard,
                _isMember <- info.isMember,
                _type <- info.type,
                _passType <- info.passType,
                _joinType <- info.joinType.rawValue,
                _joinPwd <- info.joinPwd,
                _mute <- info.mute,
                _singleMute <- info.singleMute,
                _muteRange <- info.muteRange.rawValue,
                _memberCount <- info.memberCount,
                _maxMember <- info.maxMemberCount,
                _isAdmin <- info.isAdmin,
                _fav <- info.fav,
                _showAlias <- info.showAlias,
                _timestamp <- info.timestamp,
                onConflictOf: _groupId)) >= 0
        }catch{
            print("\(error)")
        }
        return false
    }
    func delGroupInfo(_ groupId:String) ->Bool {
        do{
            return try getDb()!.run(group.filter(_groupId == groupId).delete()) > 0
        }catch{
            print("\(error)")
        }
        return false
    }
    func updateGroupInfo(_ groupId:String, updater: Setter) -> Bool {
        do{
            return try getDb()!.run(group.filter(_groupId == groupId).update(updater)) >= 0
            
        }catch{
            print("\(error)")
        }
        return false
    }
    func updateShowAlias(_ groupId:String,_ value:Bool) ->Bool {
        do{

            return try getDb()!.run(group.filter(_groupId == groupId).update(
                _showAlias <- value
                
            )) >= 0
            
        }catch{
            print("\(error)")
        }
        return false
    }
    
    func listGroupInfo(_ isFav:Bool = false) -> [DMCCGroup] {
        do{
            let sql = if isFav {group.filter(_fav == true)} else {group}
            var list:[DMCCGroup] = []
            for groups in try getDb()!.prepare(sql) {
                list.append(toInfo(groups))
            }
            return list
        }catch{
            print("\(error)")
        }
        return []
    }
    func searchGroup(_ text:String)->[DMCCGroup]{
        var ms:[DMCCGroup] = []
        do{
            for group in try getDb()!.prepare(group.filter(_alias.like("%"+text+"%") || _name.like("%"+text+"%"))) {
                let g = toInfo(group)
                ms.append(g)
            }
        }catch{
            print("\(error)")
        }
        return ms

    }

}
let dbGroup = DbGroup()
